/**
 * 节点组件相关方法
 * */

class loadSceneInterface {
    name: string;
    totalCount: number = 0;
    completed: number = 0;

    constructor(name) {
        this.name = name;
    }
}

class mapLoadInfo {
    [key: string]: loadSceneInterface;
}

class loadScenesArray {
    map: mapLoadInfo = new mapLoadInfo();
    m_overEd: boolean = false;

    constructor() {
    }

    initStart() {
    }

    initIng(): boolean {
        for (let key in this.map) {
            if (this.map[key].totalCount == 0) {
                return true;
            }
        }
        return false;
    }

    /**
     * @param {String} name
     * @param {loadSceneInterface} loadSceneInfo
     * */
    push(name: string, loadSceneInfo: loadSceneInterface) {
        this.map[name] = loadSceneInfo;
    }

    getAllTotalCount(): number {
        let count = 0;
        for (let name in this.map) {
            count += this.map[name].totalCount;
        }
        return count;
    }

    getAllCompletedCount(): number {
        let count = 0;
        for (let name in this.map) {
            count += this.map[name].completed;
        }
        return count;
    }

    setCompleted(name: string, count: number) {
        this.map[name].completed = count;
    }

    setTotalCount(name: string, count: number) {
        this.map[name].totalCount = count;
    }

    setLoaded(name: string) {
        this.map[name].completed = this.map[name].totalCount;
    }

    /**
     * @return {Boolean}
     * */
    isLoadOver(): boolean {
        //防止多次触发
        if (this.m_overEd) return false;
        //只触发一次
        this.m_overEd = this.getAllTotalCount() == this.getAllCompletedCount();
        return this.m_overEd;
    }
}

/**
 * 节点和组件方法集合
 * */
class node_component {
    /***
     * @function 下一帧执行
     * @param {cc.Component} com 组件
     * @param {Function} func 函数
     * */
    static nextTickRun(com: cc.Component, func: Function) {
        com.scheduleOnce(func, 0);
    }

    /**
     * @function 指定多少帧后执行
     * @param {cc.Component} com 组件
     * @param {Function} func 函数
     * @param {Number} num 帧数
     * */
    static numFpsAfterRun(com: cc.Component, func: Function, num: number) {
        let i = num;
        let a = () => {
            this.nextTickRun(com, () => {
                if (--i <= 0) {
                    func();
                } else {
                    a();
                }
            });
        };
        a();
    }

    /**
     * @function 合并加载场景
     * */
    static mergePreLoadScenes(sceneNames: Array<string>, onProgress?: (completedCount: number, totalCount: number, item?: any) => void, onLoaded?: () => void) {
        let loadArray = new loadScenesArray();
        loadArray.initStart();
        for (let sceneName of sceneNames) {
            loadArray.push(sceneName, new loadSceneInterface(sceneName));
            //
            cc.director.preloadScene(sceneName, (completedCount, totalCount, item) => {
                loadArray.setCompleted(sceneName, completedCount);
                loadArray.setTotalCount(sceneName, totalCount);
                if (loadArray.initIng()) return;
                onProgress && onProgress(loadArray.getAllCompletedCount(), loadArray.getAllTotalCount(), item);
            }, () => {
                loadArray.setLoaded(sceneName);
                if (loadArray.initIng()) return;
                if (loadArray.isLoadOver()) {
                    onLoaded && onLoaded();
                }
            });
        }
        //
    }

   /**
     * 加载resources 图片
     * @param url
     * @param spriteComOrSpriteNode
     */
    static async loadResourcesPicture(url: string, spriteComOrSpriteNode: cc.Sprite | cc.Node,bundle:cc.AssetManager.Bundle=cc.resources):Promise<cc.SpriteFrame> {
        return new Promise<cc.SpriteFrame>((resolve,reject)=>{
            bundle.load(url, cc.SpriteFrame, (error, spriteFrame: cc.SpriteFrame) => {
                if (error) {
                    console.error('图片不存在', url);
                    // console.error(error);
                    reject();
                    return;
                }
                
                if (spriteComOrSpriteNode instanceof cc.Node) {
                    let sprite = spriteComOrSpriteNode.getComponent(cc.Sprite)||spriteComOrSpriteNode.addComponent(cc.Sprite);
                    sprite.spriteFrame = spriteFrame;
                } else if (spriteComOrSpriteNode instanceof cc.Sprite) {
                    spriteComOrSpriteNode.spriteFrame = spriteFrame;
                } else {
                    throw '加载非图片不能使用此方法';
                }

                resolve(spriteFrame);
            });
        });
    }

    /**
     * 加载一张 图片
     * @param url
     */
     static async loadSpriteFrame(url: string,bundle:cc.AssetManager.Bundle=cc.resources):Promise<cc.SpriteFrame> {
        return new Promise<cc.SpriteFrame>((resolve)=>{
            bundle.load(url, cc.SpriteFrame, (error, spriteFrame: cc.SpriteFrame) => {
                if (error) {
                    console.error('图片不存在', url);
                    console.error(error);
                    return;
                }

                resolve(spriteFrame);
            });
        });
    }

    /**
     * 获取相对于指定父节点的位置
     * */
    static getPosOfParentNode(srcNode: cc.Node, parentNode: cc.Node): cc.Vec2 {
        let curNode = srcNode;
        let curPos = cc.v2(0, 0);
        while (curNode != parentNode) {
            curPos = curPos.add(curNode.getPosition());
            curNode = curNode.parent;
        }
        return curPos;
    }

    /**
     * 获取指定帧数时的耗时
     * */
    static getTimeOfFps(fpsCount: number) {
        return 1 / 60/*cc.game.getFrameRate()*/ * fpsCount;
    }
}

export default node_component;


































